﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenGado.Business;
using OpenGado.DATA;
using OpenGado.DATA.Entities;

namespace OpenGado.Win
{
    public partial class frmItemIssue : Form
    {
        IssueItemHeader header = new IssueItemHeader();

        public CurrModeType modeType;
        public EditMode editMode;

        private string _requestNumber; 

       public enum CurrModeType
       {
           issue, request
       }
       
        public enum EditMode
        {
            On, Off
        }

        public CurrModeType ModeType
        {
            get
            {
                return modeType;
            }
            set
            {
                modeType = value;
            }

        }

        private int headerId;

        public int HeaderId
        {
            get { return headerId; }
            set { headerId = value; }
        }
      
        public frmItemIssue()
        {
            
            InitializeComponent();          
            dgvIssue.AutoGenerateColumns = false;
            GetProjects();
          
          
        }

        public frmItemIssue(int headerId, CurrModeType currModeType)
        {

            InitializeComponent();
            dgvIssue.AutoGenerateColumns = false;
            GetProjects();

            ModeType = currModeType;
            LoadData(headerId);

        }
        /// <summary>
        /// Gets data by Header id,
        /// </summary>
        /// <param name="currentHeaderId"></param>
        private void LoadData(int currentHeaderId)
        {

            header = IssueItemsDataControl.Instance.GetIssueHeader(currentHeaderId);
            GetHeaderData(header);
            // load issue or request header 
            if (ModeType == CurrModeType.issue)
            {
                if (header.IssueItem.Count ==0)
                {
                    // convert requests into unsaved issue items.                   
                    foreach (var r in header.RequestItem)
                    {
                        IssueItem issueItem = new IssueItem();
                        issueItem.IssueItemHeader = header;
                        issueItem.Product = r.Product;
                        issueItem.IssueQuantity = r.Quanity;

                        ItemNewDataRow(issueItem, header);
                    }
                }
                else
                {
                    foreach (var i in header.IssueItem)
                    {
                        ItemNewDataRow(i, header);
                    }
                }
                
            }
            if (ModeType == CurrModeType.request)
            {
                foreach (var r in header.RequestItem)
                {
                    ItemNewDataRow(r, header);
                }
            }

        }
        /// <summary>
        /// Invoked when the users hits find button it searches based on request Number 
        /// </summary>
        /// <param name="requestNumber"></param>
        private void LoadData(String requestNumber)
        {
        
               header = IssueItemsDataControl.Instance.GetIssueHeaderByRequestId(requestNumber);
                GetHeaderData(header);
            // load issue or request header 
            if (ModeType == CurrModeType.issue)
            {
                foreach (var i in header.IssueItem)
                {
                    ItemNewDataRow(i,header); 
                }
            }

        }


        private void GetHeaderData(IssueItemHeader header)
        {
            if (header == null) return;

            txtRequestId.Text = header.RequestNumber;
            cboProject.SelectedItem = header.Project;
            txtIssueTo.Text = header.IssueTo;
            txtRemarks.Text = header.RequestComment;

            if (header.IssueDate != null)
            {
                dtpIssueDate.Value = (DateTime) header.IssueDate;
            }

        }

        private void GetProducts()
        {
            Cursor.Current = Cursors.WaitCursor;
            cboProduct.Refresh();
            IList<Product> productList = ProductDataControl.Instance.Query("Project", cboProject.Text);
            cboProduct.DataSource = productList;
            cboProduct.DisplayMember = "ProductName";
                       
            Cursor.Current = Cursors.Default;
        }

      

        /// <summary>
        /// Binds projects to the list
        /// </summary>
        private void GetProjects()
        {
            cboProject.DataSource = ProjectDataControl.Instance.GetAllProjects();
            cboProject.DisplayMember = "Name";
        }

        /// <summary>
        /// Checkes if product is already existing in the grid
        /// </summary>
        /// <param name="idToCheck"></param>
        /// <returns> -1 if nothing  isfound and row index if product is found</returns>
        private int productExists(int idToCheck)
        {
            int exists = -1;

            foreach (DataGridViewRow rw in dgvIssue.Rows)
            {
                if (rw.Cells[2].Value ==null)
                {
                    break;
                }
                else if (idToCheck == (int)rw.Cells[2].Value)
                {
                    exists = rw.Index;
                    break;
                } 

            }

            return exists;
        }

        private void ItemNewDataRow()
        {

            // check if already in the list
            int productRowIndex = productExists(GetSelectedProduct().Productid) ;
            Decimal quantity;
            Decimal subTotal;

            if (productRowIndex == -1)
            {
               // add a new line 
                DataGridViewRow rw = new DataGridViewRow();
                int n = dgvIssue.Rows.Add(rw);

                dgvIssue.Rows[n].Cells[0].Value = txtRequestId.Text;
                dgvIssue.Rows[n].Tag = GetSelectedProduct();
                dgvIssue.Rows[n].Cells[2].Value = GetSelectedProduct().Productid;
                dgvIssue.Rows[n].Cells[3].Value = GetSelectedProduct().ProductName;
                dgvIssue.Rows[n].Cells[4].Value = txtQuantity.Text;
                dgvIssue.Rows[n].Cells[5].Value = GetSelectedProduct().Sku;
                dgvIssue.Rows[n].Cells[6].Value = GetSelectedProduct().Storage.StoreName;
                dgvIssue.Rows[n].Cells[7].Value = GetSelectedProduct().CurrentPrice;

                // calculate sub total
                CalculateSubTotals();
            }
            else
            {
                Decimal newQuantity;
                Decimal oldQuantity;
                Decimal currentQuantity;
                Decimal.TryParse(txtQuantity.Text, out currentQuantity);
                Decimal.TryParse(dgvIssue.Rows[productRowIndex].Cells[4].Value.ToString(), out oldQuantity);
   
                newQuantity = oldQuantity + currentQuantity;
                dgvIssue.Rows[productRowIndex].Cells[4].Value = newQuantity;
                CalculateSubTotals();
                dgvIssue.Refresh();
            }
           
            
        }

        private void ItemNewDataRow(IssueItem  item, IssueItemHeader itemHeader)
        {

           
              Decimal quantity;
              Decimal subTotal;


              // add a new line 
                DataGridViewRow rw = new DataGridViewRow();
                int n = dgvIssue.Rows.Add(rw);

                 if (itemHeader == null) return;
                 if (item ==null) return;

                dgvIssue.Rows[n].Cells[0].Value = itemHeader.RequestNumber;
                dgvIssue.Rows[n].Cells[0].Tag = item.Product;
                dgvIssue.Rows[n].Cells[2].Value = item.Product.Productid;
                dgvIssue.Rows[n].Cells[3].Value = item.Product.ProductName;
                dgvIssue.Rows[n].Cells[4].Value = item.IssueQuantity;
                dgvIssue.Rows[n].Cells[5].Value = item.Product.Sku;
                dgvIssue.Rows[n].Cells[6].Value = item.Product.Storage.StoreName;
                dgvIssue.Rows[n].Cells[7].Value = item.Product.CurrentPrice;
                dgvIssue.Rows[n].Cells[7].Tag = item;

                // calculate sub total
                CalculateSubTotals();
           
        }

        private void ItemNewDataRow(RequestItem item, IssueItemHeader itemHeader)
        {


            Decimal quantity;
            Decimal subTotal;


            // add a new line 
            DataGridViewRow rw = new DataGridViewRow();
            int n = dgvIssue.Rows.Add(rw);

            if (itemHeader == null) return;
            if (item == null) return;

            dgvIssue.Rows[n].Cells[0].Value = itemHeader.RequestNumber;
            dgvIssue.Rows[n].Cells[0].Tag = item.Product;
            dgvIssue.Rows[n].Cells[2].Value = item.Product.Productid;
            dgvIssue.Rows[n].Cells[3].Value = item.Product.ProductName;
            dgvIssue.Rows[n].Cells[4].Value = item.Quanity;
            dgvIssue.Rows[n].Cells[5].Value = item.Product.Sku;
            dgvIssue.Rows[n].Cells[6].Value = item.Product.Storage.StoreName;
            dgvIssue.Rows[n].Cells[7].Value = item.Product.CurrentPrice;
            dgvIssue.Rows[n].Cells[7].Tag = item;

            // calculate sub total
            CalculateSubTotals();

        }

        private void CalculateSubTotals()
        {
            Decimal itemQuantity;
            Decimal price;
            Decimal subTotal; 

            foreach (DataGridViewRow rw in dgvIssue.Rows)
            {
                if (rw.Cells[4].Value != null)
                {
                    Decimal.TryParse(rw.Cells[4].Value.ToString(), out itemQuantity);
                    Decimal.TryParse(rw.Cells[7].Value.ToString(), out price);
                    subTotal = itemQuantity * price;
                    rw.Cells[8].Value = subTotal.ToString("#.##");
                }
               

            }

            txtTotal.Text =  CalculateTotalValue().ToString();
        }

        private void PopulateDataGrid()
        {
            IList<Product> productList = ProductDataControl.Instance.GetAll();

            dgvIssue.DataSource = productList;

            dgvIssue.Columns[1].DataPropertyName = "ProductName";
        }

        private Product GetSelectedProduct()
        {
            Product p = (Product) cboProduct.SelectedItem;

            return p;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (ConsistencyCheckPassed())
            {
                ItemNewDataRow();
            }
         
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private Decimal CalculateTotalValue()
        {
            Decimal runningValue =0; 
            foreach(DataGridViewRow rw in dgvIssue.Rows)
            {
                if (rw.Cells[8].Value ==null)
                {
                    break;
                }
                Decimal itemValue;
                Decimal.TryParse(rw.Cells[8].Value.ToString(), out itemValue);
                runningValue += itemValue;
            }

            return runningValue;
        }

        private List<int> GetSelectedRows()
        {
            List<int> selectedRows = new List<int>();
            foreach(DataGridViewRow rw in dgvIssue.SelectedRows)
            {
                selectedRows.Add(rw.Index);
            }

            return selectedRows;
        }
       
        /// <summary>
        /// Removes selected rows from the list
        /// </summary>
        private void RemoveRows()
        {
            foreach (DataGridViewRow rw in dgvIssue.SelectedRows)
            {
                if (rw != null)
                {
                    dgvIssue.Rows.Remove(rw);
                }
               
            }
            // we need to recalculate the order value again.
            CalculateTotalValue();
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {

            DialogResult res;
            
            res = MessageBox.Show("Are you sure you want to remove selected item(s)? ", "Inventory", MessageBoxButtons.YesNo);
            if (res == DialogResult.Yes)
            {
                RemoveRows();
            }
            
        }
        /// <summary>
        /// Checks the submitted data for consistency
        /// </summary>
        private bool ConsistencyCheckPassed()
        {
            bool pass = true;
            Decimal itemQuantity;
            Decimal.TryParse (txtQuantity.Text, out itemQuantity);
            ep.Clear();

            if (itemQuantity ==0)
            {
                pass = false;
                ep.SetError(txtQuantity, "Quantity has to be numeric and can't be 0");
            }
            else if (String.IsNullOrEmpty(txtIssueTo.Text))
            {
                pass = false; 
                ep.SetError(txtIssueTo, "Required Value");
            }
           
            else if (cboProduct.SelectedItem == null)
            {
                pass = false;
                ep.SetError(cboProduct, "Select a product from the list");
            }


            return pass;
        }

        private void cboProduct_DropDown(object sender, EventArgs e)
        {
            // make sure project is selected 
            ep.Clear();

            if (!string.IsNullOrEmpty(cboProject.Text))
            {
                GetProducts();
            }
            else
            {
                ep.SetError(cboProject, "Select Project");
            }
           
        }

        
        /// <summary>
        /// will issue items on the grid once clicked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnIssue_Click(object sender, EventArgs e)
        {
            Issue();
           // MessageBox.Show("Items issued", "Inventory", MessageBoxButtons.OK); 
            //Todo: print out the list after issue. 
        }

        /// <summary>
        ///  Issues items on the page. 
        /// </summary>
        private void Issue()
        {
            //Todo: check if this header id exists and populate the data. 

            List<IssueItem> itemList = new List<IssueItem>();
            
            // we need to check with mode is it now
            switch (modeType)
            {
                case (CurrModeType.issue):
                    {
                        header.IssueDate = dtpIssueDate.Value;
                        header.IssueTo = txtIssueTo.Text;
                        header.IssueStamp = DateTime.Now;
                        header.IssueComment = txtRemarks.Text;
                        var pj = new Project();
                        pj = (Project) cboProject.SelectedItem;
                        header.Project = pj;

                        if (dgvIssue.Rows.Count > 0)
                        {

                            // check the grid and add to issue list 
                            Decimal itemQuanity;

                            foreach (DataGridViewRow rw in dgvIssue.Rows)
                            {
                                if (rw.Tag == null) break;
                                
                                IssueItem issueItem = new IssueItem();
                                
                                if (rw.Cells[7].Tag !=null)
                                {
                                    issueItem = (IssueItem) rw.Cells[7].Tag;
                                }

                                issueItem.IssueItemHeader = header;
                                Decimal.TryParse(rw.Cells[4].Value.ToString(), out itemQuanity);
                                issueItem.IssueQuantity = itemQuanity;
                                issueItem.Product = (Product)rw.Tag;
                                itemList.Add(issueItem);
                                rw.Cells[7].Tag = issueItem;
                            }


                            ProductBusiness pb = new ProductBusiness();
                            
                            pb.IssueProducts(header, itemList);
                            ClearGrid();
              
                            LoadData(header.IssueItemHeaderId);
                        }


                        break;
                    }
                case (CurrModeType.request):
                    {
                        header.RequestDate = dtpIssueDate.Value;
                        header.RequestBy = txtIssueTo.Text;
                        header.RequestComment = txtRemarks.Text;
                        
                        ProductBusiness pb = new ProductBusiness();
                        Project pj = (Project) cboProject.SelectedItem;
                        header.Project = pj;
                        header.RequestNumber = pb.GetRequestNumber(pj.Code);

                        if (dgvIssue.Rows.Count > 0)
                        {

                            // check the grid and add to issue list 
                            Decimal itemQuanity;
                            List<RequestItem> requestItems = new List<RequestItem>();

                            foreach (DataGridViewRow rw in dgvIssue.Rows)
                            {
                                if (rw.Tag == null) break;

                                RequestItem requestItem = new RequestItem();

                                if (rw.Cells[7].Tag != null)
                                {
                                    requestItem = (RequestItem)rw.Cells[7].Tag;
                                }
                               
                                requestItem.IssueItemHeader = header;
                              
                                Decimal.TryParse(rw.Cells[4].Value.ToString(), out itemQuanity);
                                requestItem.Quanity = itemQuanity;
                                requestItem.Product = (Product)rw.Tag;
                                requestItems.Add(requestItem);
                                rw.Cells[7].Tag = requestItem;

                            }

                            pb.RequestProducts(header, requestItems);

                        }

                        break;
                    }


            }


        }

        private void ClearGrid()
        {

            dgvIssue.Rows.Clear();

        }

        private void GenRequestId()
        {
            ProductBusiness pb = new ProductBusiness();
            Project currentProject = (Project) cboProject.SelectedItem;

            if (currentProject == null) return;
            txtRequestId.Text = pb.GetRequestNumber(currentProject.Code);
        }
        private void frmItemIssue_Load(object sender, EventArgs e)
        {
            // prepare the form to look like request form
                if (ModeType == CurrModeType.request)
                {
                    this.Text = "Stores Request";
                    btnIssue.Text ="Request";
                    lblAuthorized.Visible = false;
                    txtAuthorizedBy.Visible = false;
                    lblIssuedTo.Text = "Requested by";
                    txtRequestId.Visible = false;
                    btnFind.Visible = false;

                   
                }
            // prepare form to look like issue form

            if (ModeType == CurrModeType.issue)
            {
                    this.Text = "Stores Issue";
                    btnIssue.Text = "Issue";
                    txtRequestId.Visible = true;
                    btnFind.Visible = true;
            }
        }

        private void btnFind_Click(object sender, EventArgs e)
        {
            //// find the provided request ID. 
            if (String.IsNullOrEmpty(txtRequestId.Text)) return;

            
            LoadData(txtRequestId.Text);
            
        }

        private void DisplayInfo(IssueItemHeader header)
        {
            // check mode and populate controls accordingly. 


        }

        private void cboProject_SelectedValueChanged(object sender, EventArgs e)
        {
            GenRequestId();
        }

        private void dgvIssue_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            CalculateSubTotals();
            CalculateTotalValue();
        }
    }

    }
